package cn.teaseed.view;

import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.HexUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.json.JSONUtil;
import cn.teaseed.Main;
import cn.teaseed.comn.BleConfigEntity;
import cn.teaseed.comn.CorsParam;
import cn.teaseed.comn.JobEntity;
import cn.teaseed.comn.WebSocketServer;
import javafx.event.ActionEvent;
import javafx.fxml.Initializable;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.VBox;
import javafx.scene.text.Text;
import javafx.stage.Stage;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.net.URL;
import java.util.ResourceBundle;
import java.util.concurrent.Future;

@Slf4j
@Component
public class ConfigView implements Initializable {
    public TextField listenerUrl;
    public TextField listenerPort;
    public TextField callBackUrl;
    public TextField callBackPort;
    public ComboBox<String> jobMethod;
    public VBox initial;
    public Button confirmButton;
    public Button returnButton;
    public TextField remark;
    //----------DG-LAB ↓----------
    public ComboBox<String> waveA;
    public ComboBox<String> waveB;
    public TextField waveATime;
    public TextField waveBTime;
    public TextField waveAStrength;
    public TextField waveBStrength;
    public CheckBox relativeStrength;
    public TextField maxListenerValue;
    //----------Http ↓----------
    public CheckBox httpDataJp;
    public TextField httpDataJpText;
    public CheckBox httpDataFormat;
    public TextArea httpDataFormatText;
    public CheckBox httpTryTran;
    public ComboBox<String> httpTryTranBox;
    public Text pollTime;
    public Slider pollTimeSlider;
    //----------BLEDevice ↓----------
    public ComboBox<String> deviceList;
    public ComboBox<String> presetList;
    public Button addPreset;
    public Button deletePreset;
    public CheckBox conversionHex;
    public TextArea sourceData;
    public Spinner<Integer> cut;
    public Spinner<Integer> outData;
    public TextArea soutData;


    @Resource
    private HomeView homeView;
    private JobEntity cache;
    public static Boolean blePreviewStatus = true;

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        //交互类型
        jobMethod.getItems().setAll("DG-LAB", "Http", "蓝牙心率广播");
        //不同类型初始化下拉数据
        switch (jobMethod.getPromptText()) {
            case "DG-LAB": {
                //加载波形数据
                waveA.getItems().setAll(CorsParam.WaveMap.keySet());
                waveB.getItems().setAll(CorsParam.WaveMap.keySet());
                break;
            }
            case "Http": {
                httpTryTranBox.getItems().setAll("String", "Number");
                pollTimeSlider.valueProperty().addListener((observable, oldValue, newValue) ->
                        pollTime.setText(String.valueOf(newValue.intValue())));
                break;
            }
            case "蓝牙心率广播": {
                if (CorsParam.BleDevice != null) deviceList.getItems().setAll(CorsParam.BleDevice.keySet());
                presetList.getItems().setAll(CorsParam.BleConfig.keySet());
                break;
            }
            default:
                break;
        }

        //跳转用数据加载
        JobEntity o = (JobEntity) CorsParam.fifoCache.get("Config");
        cache = o;
        if (o != null) {
            switch (o.getJobMethod()) {
                case "DG-LAB": {
                    listenerUrl.setEditable(false);
                    //不为空则为列表跳转
                    listenerUrl.setText(o.getListener());
                    listenerPort.setText(o.getListenerPort());
                    callBackUrl.setText(o.getCallback());
                    callBackPort.setText(o.getCallBackPort());
                    remark.setText(o.getRemark());
                    waveA.setValue(o.getWaveA());
                    waveB.setValue(o.getWaveB());
                    waveATime.setText(o.getWaveATime());
                    waveBTime.setText(o.getWaveBTime());
                    waveAStrength.setText(o.getWaveAStrength());
                    waveBStrength.setText(o.getWaveBStrength());
                    if (o.getRelativeStrength() != null) {
                        relativeStrength.setSelected(o.getRelativeStrength());
                    }
                    maxListenerValue.setText(o.getMaxListenerValue());
                    break;
                }
                case "Http": {
                    //不为空则为列表跳转
                    listenerUrl.setText(o.getListener());
                    listenerPort.setText(o.getListenerPort());
                    callBackUrl.setText(o.getCallback());
                    callBackPort.setText(o.getCallBackPort());
                    remark.setText(o.getRemark());
                    if (o.getHttpDataJp() != null) httpDataJp.setSelected(o.getHttpDataJp());
                    httpDataJpText.setText(o.getHttpDataJpText());
                    if (o.getHttpDataFormat() != null) httpDataFormat.setSelected(o.getHttpDataFormat());
                    httpDataFormatText.setText(o.getHttpDataFormatText());
                    pollTime.setText(o.getPollTime());
                    pollTimeSlider.setValue(Double.parseDouble(o.getPollTime()));
                    break;
                }
            }
            //清除缓存防止新建窗口读取
            CorsParam.fifoCache.clear();
        }
    }

    /**
     * 根据下拉框类型切换参数
     */
    public void switchType(ActionEvent actionEvent) throws Exception {
        switch (jobMethod.getValue()) {
            // todo 页面切换类型容器冲突
            case "DG-LAB": {
                String selectedItem = jobMethod.getSelectionModel().getSelectedItem();
                if (selectedItem != null) {
                    Stage primaryStage = (Stage) initial.getScene().getWindow();
                    Scene scene = new Scene(Main.loadView("config-DGLAB.fxml"));
                    primaryStage.setScene(scene);
                    primaryStage.show();
                }
                break;
            }
            case "蓝牙心率广播": {
                String selectedItem = jobMethod.getSelectionModel().getSelectedItem();
                if (selectedItem != null) {
                    Stage primaryStage = (Stage) initial.getScene().getWindow();
                    Scene scene = new Scene(Main.loadView("config-BleDevice.fxml"));
                    primaryStage.setScene(scene);
                    primaryStage.show();
                    primaryStage.setOnCloseRequest(event -> {
                        blePreviewStatus = false;
                    });
                }
                break;
            }
            case "Http": {
                String selectedItem = jobMethod.getSelectionModel().getSelectedItem();
                if (selectedItem != null) {
                    Stage primaryStage = (Stage) initial.getScene().getWindow();
                    Scene scene = new Scene(Main.loadView("config-Http.fxml"));
                    primaryStage.setScene(scene);
                    primaryStage.show();
                }
                break;
            }
        }
    }

    /**
     * 取消
     */
    public void closeWindow(ActionEvent actionEvent) {
        blePreviewStatus = false;
        Stage window = (Stage) returnButton.getScene().getWindow();
        window.close();
    }

    /**
     * 添加任务
     */
    public void confirmData(ActionEvent actionEvent) {
        //校验是否有重复项
        String text = listenerUrl.getText();


        switch (jobMethod.getPromptText()) {
            case "DG-LAB": {
                if (cache != null && cache.getId() != null) {
                    cache.setListener(listenerUrl.getText());
                    cache.setListenerPort(listenerPort.getText());
                    cache.setJobMethod(jobMethod.getPromptText());
                    cache.setCallback(callBackUrl.getText());
                    cache.setCallBackPort(callBackPort.getText());
                    cache.setRemark(remark.getText());
                    cache.setWaveA(waveA.getValue());
                    cache.setWaveB(waveB.getValue());
                    cache.setWaveATime(waveATime.getText());
                    cache.setWaveBTime(waveBTime.getText());
                    cache.setWaveAStrength(waveAStrength.getText());
                    cache.setWaveBStrength(waveBStrength.getText());
                    cache.setRelativeStrength(relativeStrength.isSelected());
                    cache.setMaxListenerValue(maxListenerValue.getText());
                    homeView.refreshJob();
                } else {
                    homeView.addJob(new JobEntity(
                            listenerUrl.getText(),
                            listenerPort.getText(),
                            jobMethod.getPromptText(),
                            callBackUrl.getText(),
                            callBackPort.getText(),
                            remark.getText(),
                            waveA.getValue(),
                            waveB.getValue(),
                            waveATime.getText(),
                            waveBTime.getText(),
                            waveAStrength.getText(),
                            waveBStrength.getText(),
                            relativeStrength.isSelected(),
                            maxListenerValue.getText()
                    ));
                }
                break;
            }
            case "Http": {
                if (cache != null && cache.getId() != null) {
                    cache.setListener(listenerUrl.getText());
                    cache.setListenerPort(listenerPort.getText());
                    cache.setJobMethod(jobMethod.getPromptText());
                    cache.setCallback(callBackUrl.getText());
                    cache.setCallBackPort(callBackPort.getText());
                    cache.setRemark(remark.getText());
                    cache.setHttpDataJp(httpDataJp.isSelected());
                    cache.setHttpDataJpText(httpDataJpText.getText());
                    cache.setHttpDataFormat(httpDataFormat.isSelected());
                    cache.setHttpDataFormatText(httpDataFormatText.getText());
                    cache.setPollTime(pollTime.getText());
                    homeView.refreshJob();
                } else {
                    homeView.addJob(new JobEntity(
                            listenerUrl.getText(),
                            listenerPort.getText(),
                            jobMethod.getPromptText(),
                            callBackUrl.getText(),
                            callBackPort.getText(),
                            remark.getText(),
                            httpDataJp.isSelected(),
                            httpDataJpText.getText(),
                            httpDataFormat.isSelected(),
                            httpDataFormatText.getText(),
                            pollTime.getText()
                    ));
                }
                break;
            }
            default:
                break;
        }

        Stage window = (Stage) confirmButton.getScene().getWindow();
        window.close();
    }

    /**
     * Ble设备下拉菜单
     */
    public void switchBleData(ActionEvent actionEvent) {
        String bleName = deviceList.getValue();
        String bleMac = CorsParam.BleDevice.get(bleName);
        String configStart = CorsParam.BleComp.get(bleName);
        BleConfigEntity config = CorsParam.BleConfig.get(configStart);

        presetList.setValue(configStart);
        cut.getValueFactory().setValue(config.getCut());
        outData.getValueFactory().setValue(config.getOutData() + 1);

        if (bleName.equals(CorsParam.CurrentlyConnectedDevice)) {
            log.info("已启用实时预览");
            //选中的是当前的已连接的设备,显示数据预览
            ThreadUtil.execAsync(() -> {
                while (blePreviewStatus) {
                    try {
                        String body = HttpRequest.get(StrUtil.format("http://127.0.0.1:9365/getHeartNumHex", bleMac))
                                .timeout(500)//超时，毫秒
                                .execute().body();
                        body = body.replaceAll("\\n", "");
                        body = body.replaceAll("\"(.*)\"", "$1");
                        byte[] bytes = HexUtil.decodeHex(body);

                        sourceData.clear();
                        sourceData.setText(JSONUtil.toJsonStr(bytes));

                        soutData.clear();
                        //不取配置对象的原因：切换其他的Config需要实时修改显示 故读取总数据
                        soutData.setText(String.valueOf(bytes[outData.getValue() - 1]));
                    } catch (Exception e) {
                        log.error("实时预览出现异常：{}", e.getMessage());
                    }
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException ignored) {
                    }
                }
                log.info("实时预览已结束");
            });
        }
    }

    /**
     * Ble配置下拉菜单
     */
    public void switchBleConfig(ActionEvent actionEvent) {
        String conName = presetList.getValue();
        BleConfigEntity config = CorsParam.BleConfig.get(conName);

        cut.getValueFactory().setValue(config.getCut());
        outData.getValueFactory().setValue(config.getOutData() + 1);
    }

    /**
     * 添加Ble配置
     */
    public void addBleConfig(ActionEvent actionEvent) {

    }

    /**
     * 删除Ble配置
     */
    public void deleteBleConfig(ActionEvent actionEvent) {

    }
}
